package com.michaelbulava.TFS.vcs.internal;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.*;
import com.michaelbulava.TFS.vc.tfsitem.TFSFile;
import com.michaelbulava.TFS.vcs.TFSVcs;
import com.michaelbulava.TFS.vcs.revision.TFSContentRevision;
import com.michaelbulava.TFS.vcs.utils.TFSFileUtil;
import com.microsoft.tfs.core.clients.versioncontrol.WorkspaceLocation;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace;

/**
 * Created by MichaelA on 8/5/2015.
 */
public class ChangelistBuilderStatusVisitor extends StatusVisitor {
    private final Project myProject;
    private final ChangelistBuilder myBuilder;
    private final Workspace myWorkspace;

    public ChangelistBuilderStatusVisitor(Project project, ChangelistBuilder builder, Workspace workspace) {
        this.myProject = project;
        this.myBuilder = builder;
        this.myWorkspace = workspace;
    }

    @Override
    protected void performNotVersion(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        if (existsLocally)
            myBuilder.processUnversionedFile(filePath.getVirtualFile());
    }

    @Override
    protected void performDeleted(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        if (existsLocally)
            myBuilder.processUnversionedFile(filePath.getVirtualFile());
    }

    @Override
    protected void performScheduledForAddition(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        if (existsLocally)
            myBuilder.processChange(new Change(null, new CurrentContentRevision(filePath)), TFSVcs.getKey());
        else
            myBuilder.processLocallyDeletedFile(filePath);
    }

    @Override
    protected void performScheduledForDeletion(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        TFSContentRevision baseRevision = TFSContentRevision.create(myProject, myWorkspace, filePath,
                serverStatus.localVersion, serverStatus.itemId);
        this.myBuilder.processChange(new Change(baseRevision, null), TFSVcs.getKey());
    }

    @Override
    protected void performCheckedOutForEdit(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        if (existsLocally){
            TFSContentRevision baseRevision = TFSContentRevision.create(myProject, myWorkspace, filePath,
                    serverStatus.localVersion, serverStatus.itemId);
            myBuilder.processChange(new Change(baseRevision, CurrentContentRevision.create(filePath)), TFSVcs.getKey());
        } else
            myBuilder.processLocallyDeletedFile(filePath);
    }

    @Override
    protected void performOutOfDate(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        ServerStatus.OutOfDate outOfDateStatus = (ServerStatus.OutOfDate) serverStatus;
        if (existsLocally){
            if (TFSFileUtil.isFileWritable(filePath) && myWorkspace.getLocation() != WorkspaceLocation.LOCAL){
                myBuilder.processModifiedWithoutCheckout(filePath.getVirtualFile());
            } else{
                //TODO need to put these into the Incomming Change list
//                TFSContentRevision localVersion = TFSContentRevision.create(myProject, myWorkspace, filePath,
//                        outOfDateStatus.getExtendedItem().getLocalVersion(), outOfDateStatus.itemId);
//                TFSContentRevision serverVersion = TFSContentRevision.create(myProject, myWorkspace, filePath,
//                        outOfDateStatus.getExtendedItem().getLatestVersion(), outOfDateStatus.itemId);
//                myBuilder.processChange(new Change(null, serverVersion), TFSVcs.getKey());
            }
        } else {
            //myBuilder.processChange(new Change(null, CurrentContentRevision.create(filePath)), TFSVcs.getKey());
            myBuilder.processLocallyDeletedFile(filePath);
        }


    }

    @Override
    protected void performUpToDate(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        if (existsLocally){
            if (TFSFileUtil.isFileWritable(filePath) && !serverStatus.IsLocalWorkspace())
                myBuilder.processModifiedWithoutCheckout(filePath.getVirtualFile());
        } else
            myBuilder.processLocallyDeletedFile(filePath);
    }

    @Override
    protected void performRenamed(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        if (existsLocally){
            String serverLocation = myWorkspace.getMappedLocalPath(serverStatus.sourceItem);
            FilePath beforePath = TFSFileUtil.getFilePath(serverLocation, serverStatus.isDirectory);

            TFSContentRevision before = TFSContentRevision.create(myProject, myWorkspace, beforePath,
                    serverStatus.localVersion, serverStatus.itemId);
            ContentRevision after = CurrentContentRevision.create(filePath);

            myBuilder.processChange(new Change(before, after), TFSVcs.getKey());
        } else
            myBuilder.processLocallyDeletedFile(filePath);
    }

    @Override
    protected void performRenamedCheckedOut(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        performRenamed(filePath, existsLocally, serverStatus);
    }

    @Override
    protected void performUndeleted(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        checkedOutForEdit(filePath, existsLocally, serverStatus);
    }

    @Override
    protected void performIgnored(FilePath filePath, boolean existsLocally, ServerStatus serverStatus) {
        myBuilder.processIgnoredFile(filePath.getVirtualFile());
    }

    @Override
    public void WorkingFolder(FilePath folder){
        super.WorkingFolder(folder);
    }



}
